//! # API Key认证提供者
//!
//! 实现基于API Key的简单认证方式，适用于服务间通信和第三方集成。
//!
//! ## 功能特性
//!
//! * **多种Key格式** - 支持Header、Query参数传递API Key
//! * **Key管理** - 支持动态添加、删除、更新API Key
//! * **权限映射** - 每个API Key可配置不同的权限
//! * **使用统计** - 记录API Key的使用情况
//! * **限流支持** - 支持per-key的限流配置
//!
//! ## 使用示例
//!
//! ```rust
//! use rustcloud_gateway::auth::api_key::*;
//!
//! // 创建API Key认证提供者
//! let mut provider = ApiKeyAuthProvider::new();
//! 
//! // 添加API Key
//! let key_info = ApiKeyInfo::new("service1", vec!["read:users".to_string()]);
//! provider.add_key("sk_test_123456", key_info).await?;
//!
//! // 认证请求
//! let context = AuthContext::new(headers, method, uri, remote_addr);
//! let principal = provider.authenticate(&context).await?;
//! ```

use super::{AuthProvider, AuthContext, Principal, Resource, AuthResult, AuthError, 
           AuthProviderType, PrincipalType};
use rustcloud_security::providers::AuthorizationProvider;
// 导入新的Principal构建器和权限检查器工具
use rustcloud_core::auth::{PrincipalConverter, PermissionCheckerFactory};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, SystemTime};
use tokio::sync::RwLock;
use tracing::{debug, warn, error};

/// API Key信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiKeyInfo {
    /// Key标识符
    pub id: String,
    /// Key名称
    pub name: String,
    /// 关联的服务或用户
    pub owner: String,
    /// 权限列表
    pub permissions: Vec<String>,
    /// 角色列表
    pub roles: Vec<String>,
    /// 是否激活
    pub active: bool,
    /// 创建时间
    pub created_at: SystemTime,
    /// 最后使用时间
    pub last_used_at: Option<SystemTime>,
    /// 过期时间
    pub expires_at: Option<SystemTime>,
    /// 使用次数
    pub usage_count: u64,
    /// 每日限制
    pub daily_limit: Option<u64>,
    /// 自定义属性
    pub attributes: HashMap<String, String>,
}

impl ApiKeyInfo {
    /// 创建新的API Key信息
    pub fn new(owner: String, permissions: Vec<String>) -> Self {
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            name: format!("API Key for {}", owner),
            owner,
            permissions,
            roles: Vec::new(),
            active: true,
            created_at: SystemTime::now(),
            last_used_at: None,
            expires_at: None,
            usage_count: 0,
            daily_limit: None,
            attributes: HashMap::new(),
        }
    }

    /// 设置名称
    pub fn with_name(mut self, name: String) -> Self {
        self.name = name;
        self
    }

    /// 添加角色
    pub fn add_role(mut self, role: String) -> Self {
        self.roles.push(role);
        self
    }

    /// 设置过期时间
    pub fn with_expiry(mut self, expires_at: SystemTime) -> Self {
        self.expires_at = Some(expires_at);
        self
    }

    /// 设置每日限制
    pub fn with_daily_limit(mut self, limit: u64) -> Self {
        self.daily_limit = Some(limit);
        self
    }

    /// 添加属性
    pub fn add_attribute(mut self, key: String, value: String) -> Self {
        self.attributes.insert(key, value);
        self
    }

    /// 检查是否过期
    pub fn is_expired(&self) -> bool {
        if let Some(expires_at) = self.expires_at {
            SystemTime::now() > expires_at
        } else {
            false
        }
    }

    /// 检查是否超出每日限制
    pub fn is_daily_limit_exceeded(&self) -> bool {
        if let Some(daily_limit) = self.daily_limit {
            if let Some(last_used) = self.last_used_at {
                // 简化版本：这里应该根据实际日期来计算
                // 在生产环境中，应该使用更精确的日期计算
                let now = SystemTime::now();
                if let Ok(duration) = now.duration_since(last_used) {
                    if duration < Duration::from_secs(24 * 60 * 60) {
                        return self.usage_count >= daily_limit;
                    }
                }
            }
        }
        false
    }

    /// 更新使用统计
    pub fn update_usage(&mut self) {
        self.last_used_at = Some(SystemTime::now());
        self.usage_count += 1;
    }
}

/// API Key配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiKeyConfig {
    /// 默认权限
    pub default_permissions: Vec<String>,
    /// Key前缀
    pub key_prefix: Option<String>,
    /// Key长度
    pub key_length: usize,
    /// 是否大小写敏感
    pub case_sensitive: bool,
    /// 支持的Header名称
    pub header_names: Vec<String>,
    /// 查询参数名称
    pub query_param_name: String,
    /// 是否启用使用统计
    pub enable_usage_stats: bool,
}

impl Default for ApiKeyConfig {
    fn default() -> Self {
        Self {
            default_permissions: Vec::new(),
            key_prefix: Some("sk_".to_string()),
            key_length: 32,
            case_sensitive: true,
            header_names: vec![
                "X-API-Key".to_string(),
                "X-Api-Key".to_string(),
                "Authorization".to_string(),
            ],
            query_param_name: "api_key".to_string(),
            enable_usage_stats: true,
        }
    }
}

/// API Key使用统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiKeyStats {
    pub total_keys: usize,
    pub active_keys: usize,
    pub total_requests: u64,
    pub requests_last_24h: u64,
    pub top_keys: Vec<(String, u64)>, // (key_id, usage_count)
}

/// API Key认证提供者
pub struct ApiKeyAuthProvider {
    config: ApiKeyConfig,
    keys: Arc<RwLock<HashMap<String, ApiKeyInfo>>>,
    key_cache: Arc<RwLock<HashMap<String, String>>>, // hash -> key_id for performance
    /// 权限检查器（使用新的统一实现）
    permission_checker: Arc<dyn rustcloud_security::PermissionChecker>,
}

impl ApiKeyAuthProvider {
    /// 创建新的API Key认证提供者
    pub fn new() -> Self {
        Self::with_config(ApiKeyConfig::default())
    }

    /// 使用配置创建提供者
    pub fn with_config(config: ApiKeyConfig) -> Self {
        Self {
            config,
            keys: Arc::new(RwLock::new(HashMap::new())),
            key_cache: Arc::new(RwLock::new(HashMap::new())),
            // 使用新的统一权限检查器
            permission_checker: Arc::new(PermissionCheckerFactory::create_default()),
        }
    }

    /// 添加API Key
    pub async fn add_key(&self, key: String, mut info: ApiKeyInfo) -> AuthResult<()> {
        // 验证Key格式
        self.validate_key_format(&key)?;

        // 检查Key是否已存在
        {
            let keys = self.keys.read().await;
            if keys.contains_key(&key) {
                return Err(AuthError::InternalError(format!("API Key already exists: {}", key)));
            }
        }

        // 添加默认权限
        for perm in &self.config.default_permissions {
            if !info.permissions.contains(perm) {
                info.permissions.push(perm.clone());
            }
        }

        // 存储Key
        {
            let mut keys = self.keys.write().await;
            keys.insert(key.clone(), info.clone());
        }

        // 更新缓存
        {
            let mut cache = self.key_cache.write().await;
            cache.insert(self.hash_key(&key), key);
        }

        debug!("Added API Key for owner: {}", info.owner);
        Ok(())
    }

    /// 删除API Key
    pub async fn remove_key(&self, key: &str) -> AuthResult<bool> {
        let removed = {
            let mut keys = self.keys.write().await;
            keys.remove(key).is_some()
        };

        if removed {
            let mut cache = self.key_cache.write().await;
            cache.remove(&self.hash_key(key));
            debug!("Removed API Key: {}", key);
        }

        Ok(removed)
    }

    /// 更新API Key信息
    pub async fn update_key(&self, key: &str, info: ApiKeyInfo) -> AuthResult<()> {
        let mut keys = self.keys.write().await;
        
        if keys.contains_key(key) {
            keys.insert(key.to_string(), info);
            debug!("Updated API Key: {}", key);
            Ok(())
        } else {
            Err(AuthError::InternalError(format!("API Key not found: {}", key)))
        }
    }

    /// 获取API Key信息
    pub async fn get_key_info(&self, key: &str) -> Option<ApiKeyInfo> {
        let keys = self.keys.read().await;
        keys.get(key).cloned()
    }

    /// 列出所有API Key
    pub async fn list_keys(&self) -> Vec<(String, ApiKeyInfo)> {
        let keys = self.keys.read().await;
        keys.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
    }

    /// 生成新的API Key
    pub fn generate_key(&self) -> String {
        let mut key = String::new();
        
        if let Some(ref prefix) = self.config.key_prefix {
            key.push_str(prefix);
        }

        // 生成随机字符串
        let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        for _ in 0..self.config.key_length {
            let idx = rand::random::<usize>() % charset.len();
            key.push(charset[idx] as char);
        }

        key
    }

    /// 验证Key格式
    fn validate_key_format(&self, key: &str) -> AuthResult<()> {
        if key.is_empty() {
            return Err(AuthError::InvalidToken("API Key cannot be empty".to_string()));
        }

        if let Some(ref prefix) = self.config.key_prefix {
            if !key.starts_with(prefix) {
                return Err(AuthError::InvalidToken(format!("API Key must start with '{}'", prefix)));
            }
        }

        Ok(())
    }

    /// 哈希Key用于缓存
    fn hash_key(&self, key: &str) -> String {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};

        let mut hasher = DefaultHasher::new();
        key.hash(&mut hasher);
        format!("{:x}", hasher.finish())
    }

    /// 从请求上下文提取API Key
    fn extract_api_key(&self, context: &AuthContext) -> Option<String> {
        // 1. 检查Header
        for header_name in &self.config.header_names {
            if let Some(value) = context.get_header(header_name) {
                // 处理Authorization header中的API Key
                if header_name.eq_ignore_ascii_case("authorization") {
                    if let Some(key) = value.strip_prefix("ApiKey ") {
                        return Some(key.to_string());
                    } else if let Some(key) = value.strip_prefix("Bearer ") {
                        // 有些系统将API Key放在Bearer中
                        return Some(key.to_string());
                    }
                } else {
                    return Some(value.to_string());
                }
            }
        }

        // 2. 检查查询参数
        if let Some(key) = context.query_params.get(&self.config.query_param_name) {
            return Some(key.clone());
        }

        None
    }

    /// 更新Key使用统计
    async fn update_key_usage(&self, key: &str) -> AuthResult<()> {
        if !self.config.enable_usage_stats {
            return Ok(());
        }

        let mut keys = self.keys.write().await;
        if let Some(info) = keys.get_mut(key) {
            info.update_usage();
        }

        Ok(())
    }

    /// 获取使用统计
    pub async fn get_stats(&self) -> ApiKeyStats {
        let keys = self.keys.read().await;
        
        let total_keys = keys.len();
        let active_keys = keys.values().filter(|info| info.active && !info.is_expired()).count();
        let total_requests: u64 = keys.values().map(|info| info.usage_count).sum();
        
        // 计算最近24小时的请求（简化版本）
        let now = SystemTime::now();
        let requests_last_24h: u64 = keys.values()
            .filter(|info| {
                if let Some(last_used) = info.last_used_at {
                    if let Ok(duration) = now.duration_since(last_used) {
                        return duration < Duration::from_secs(24 * 60 * 60);
                    }
                }
                false
            })
            .map(|info| info.usage_count)
            .sum();

        // 获取使用最多的前5个Key
        let mut top_keys: Vec<_> = keys.iter()
            .map(|(_, info)| (info.id.clone(), info.usage_count))
            .collect();
        top_keys.sort_by(|a, b| b.1.cmp(&a.1));
        top_keys.truncate(5);

        ApiKeyStats {
            total_keys,
            active_keys,
            total_requests,
            requests_last_24h,
            top_keys,
        }
    }

    /// 从ApiKeyInfo创建Principal（使用新的构建器工具）
    fn create_principal(&self, key_info: &ApiKeyInfo) -> Principal {
        // 使用 PrincipalConverter 从 API Key 信息创建 Principal
        PrincipalConverter::from_api_key_info(
            key_info.id.clone(),
            key_info.owner.clone(),
            key_info.roles.clone(),
            key_info.permissions.clone(),
            key_info.attributes.clone(),
            key_info.expires_at,
        ).name(key_info.name.clone())
         .build()
    }
}

impl Default for ApiKeyAuthProvider {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl AuthProvider for ApiKeyAuthProvider {
    async fn authenticate(&self, context: &AuthContext) -> AuthResult<Principal> {
        debug!("Authenticating API Key for request: {} {}", context.method, context.uri);

        // 提取API Key
        let api_key = self.extract_api_key(context)
            .ok_or_else(|| AuthError::AuthenticationFailed("Missing API Key".to_string()))?;

        // 查找Key信息
        let key_info = {
            let keys = self.keys.read().await;
            let normalized_key = if self.config.case_sensitive {
                api_key.clone()
            } else {
                api_key.to_lowercase()
            };
            
            keys.get(&normalized_key).cloned()
        };

        let mut key_info = key_info
            .ok_or_else(|| AuthError::AuthenticationFailed("Invalid API Key".to_string()))?;

        // 检查Key是否激活
        if !key_info.active {
            return Err(AuthError::AuthenticationFailed("API Key is disabled".to_string()));
        }

        // 检查Key是否过期
        if key_info.is_expired() {
            return Err(AuthError::TokenExpired);
        }

        // 检查每日限制
        if key_info.is_daily_limit_exceeded() {
            return Err(AuthError::AuthenticationFailed("Daily API Key limit exceeded".to_string()));
        }

        // 更新使用统计
        if let Err(e) = self.update_key_usage(&api_key).await {
            warn!("Failed to update API Key usage stats: {}", e);
        }

        // 创建Principal
        let principal = self.create_principal(&key_info);

        debug!("API Key authentication successful for owner: {}", key_info.owner);
        Ok(principal)
    }

    async fn validate_token(&self, token: &str) -> AuthResult<bool> {
        let keys = self.keys.read().await;
        let normalized_key = if self.config.case_sensitive {
            token.to_string()
        } else {
            token.to_lowercase()
        };

        if let Some(info) = keys.get(&normalized_key) {
            Ok(info.active && !info.is_expired() && !info.is_daily_limit_exceeded())
        } else {
            Ok(false)
        }
    }

    fn provider_type(&self) -> AuthProviderType {
        AuthProviderType::ApiKey
    }

    fn provider_name(&self) -> &str {
        "api_key"
    }

    async fn logout(&self, _principal: &Principal) -> AuthResult<()> {
        // API Key 一般不需要特殊的注销处理
        // 可以在这里添加禁用 Key 的逻辑
        Ok(())
    }

    async fn get_user_info(&self, principal: &Principal) -> AuthResult<serde_json::Value> {
        Ok(serde_json::json!({
            "id": principal.id,
            "name": principal.name,
            "type": principal.principal_type,
            "roles": principal.roles,
            "permissions": principal.permissions,
            "attributes": principal.attributes
        }))
    }
}

/// API Key授权提供者实现（使用新的统一权限检查器）
#[async_trait]
impl AuthorizationProvider for ApiKeyAuthProvider {
    async fn authorize(&self, principal: &Principal, resource: &Resource) -> AuthResult<bool> {
        debug!("Authorizing API Key {} for resource {}", principal.id, resource.get_resource_id());

        // 使用新的统一权限检查器
        self.permission_checker.check_resource(principal, resource).await
    }

    async fn check_permission(&self, principal: &Principal, permission: &str) -> AuthResult<bool> {
        // 使用新的统一权限检查器
        self.permission_checker.check(principal, permission).await
    }

    async fn get_user_permissions(&self, principal: &Principal) -> AuthResult<Vec<String>> {
        Ok(principal.get_permissions().iter().cloned().collect())
    }

    async fn get_user_roles(&self, principal: &Principal) -> AuthResult<Vec<String>> {
        Ok(principal.get_roles().iter().cloned().collect())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use axum::http::HeaderMap;
    use std::time::Duration;

    #[tokio::test]
    async fn test_api_key_provider_creation() {
        let provider = ApiKeyAuthProvider::new();
        assert_eq!(provider.get_provider_name(), "api_key");
        assert_eq!(provider.get_provider_type(), AuthProviderType::ApiKey);
    }

    #[tokio::test]
    async fn test_api_key_generation() {
        let provider = ApiKeyAuthProvider::new();
        let key = provider.generate_key();
        
        assert!(key.starts_with("sk_"));
        assert!(key.len() > 10);
    }

    #[tokio::test]
    async fn test_add_and_get_api_key() {
        let provider = ApiKeyAuthProvider::new();
        let key = "sk_test_123456";
        let info = ApiKeyInfo::new("test_user".to_string(), vec!["read:users".to_string()]);

        let result = provider.add_key(key.to_string(), info.clone()).await;
        assert!(result.is_ok());

        let retrieved_info = provider.get_key_info(key).await;
        assert!(retrieved_info.is_some());
        assert_eq!(retrieved_info.unwrap().owner, "test_user");
    }

    #[tokio::test]
    async fn test_api_key_authentication_success() {
        let provider = ApiKeyAuthProvider::new();
        let key = "sk_test_123456";
        let info = ApiKeyInfo::new("test_user".to_string(), vec!["read:users".to_string()]);

        provider.add_key(key.to_string(), info).await.unwrap();

        // 创建认证上下文（使用Header）
        let mut headers = HeaderMap::new();
        headers.insert("x-api-key", key.parse().unwrap());
        
        let context = AuthContext::new(
            headers,
            "GET".to_string(),
            "/api/users".to_string(),
            Some("127.0.0.1".to_string()),
        );

        let result = provider.authenticate(&context).await;
        assert!(result.is_ok());
        
        let principal = result.unwrap();
        assert!(principal.has_permission("read:users"));
    }

    #[tokio::test]
    async fn test_api_key_authentication_query_param() {
        let provider = ApiKeyAuthProvider::new();
        let key = "sk_test_123456";
        let info = ApiKeyInfo::new("test_user".to_string(), vec!["read:users".to_string()]);

        provider.add_key(key.to_string(), info).await.unwrap();

        // 创建认证上下文（使用查询参数）
        let headers = HeaderMap::new();
        let mut query_params = HashMap::new();
        query_params.insert("api_key".to_string(), key.to_string());
        
        let context = AuthContext::new(
            headers,
            "GET".to_string(),
            "/api/users".to_string(),
            Some("127.0.0.1".to_string()),
        ).with_query_params(query_params);

        let result = provider.authenticate(&context).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_api_key_authentication_missing_key() {
        let provider = ApiKeyAuthProvider::new();
        
        let headers = HeaderMap::new();
        let context = AuthContext::new(
            headers,
            "GET".to_string(),
            "/api/users".to_string(),
            Some("127.0.0.1".to_string()),
        );

        let result = provider.authenticate(&context).await;
        assert!(result.is_err());
        assert!(matches!(result.unwrap_err(), AuthError::AuthenticationFailed(_)));
    }

    #[tokio::test]
    async fn test_api_key_authentication_invalid_key() {
        let provider = ApiKeyAuthProvider::new();
        
        let mut headers = HeaderMap::new();
        headers.insert("x-api-key", "invalid_key".parse().unwrap());
        
        let context = AuthContext::new(
            headers,
            "GET".to_string(),
            "/api/users".to_string(),
            Some("127.0.0.1".to_string()),
        );

        let result = provider.authenticate(&context).await;
        assert!(result.is_err());
        assert!(matches!(result.unwrap_err(), AuthError::AuthenticationFailed(_)));
    }

    #[tokio::test]
    async fn test_api_key_authorization() {
        let provider = ApiKeyAuthProvider::new();

        let principal = Principal::new(
            "api_key_1".to_string(),
            "Test API Key".to_string(),
            PrincipalType::Service,
        ).add_permission("user-service:read".to_string());

        let resource = Resource::new(
            "user-service".to_string(),
            "/api/users".to_string(),
            "GET".to_string(),
        );

        let result = provider.authorize(&principal, &resource).await;
        assert!(result.is_ok());
        assert!(result.unwrap());
    }

    #[tokio::test]
    async fn test_api_key_expired() {
        let provider = ApiKeyAuthProvider::new();
        let key = "sk_test_expired";
        
        let past_time = SystemTime::now() - Duration::from_secs(3600);
        let info = ApiKeyInfo::new("test_user".to_string(), vec!["read:users".to_string()])
            .with_expiry(past_time);

        provider.add_key(key.to_string(), info).await.unwrap();

        let mut headers = HeaderMap::new();
        headers.insert("x-api-key", key.parse().unwrap());
        
        let context = AuthContext::new(
            headers,
            "GET".to_string(),
            "/api/users".to_string(),
            Some("127.0.0.1".to_string()),
        );

        let result = provider.authenticate(&context).await;
        assert!(result.is_err());
        assert!(matches!(result.unwrap_err(), AuthError::TokenExpired));
    }

    #[tokio::test]
    async fn test_api_key_stats() {
        let provider = ApiKeyAuthProvider::new();
        
        // 添加几个测试Key
        for i in 0..3 {
            let key = format!("sk_test_{}", i);
            let info = ApiKeyInfo::new(
                format!("user_{}", i),
                vec![format!("permission_{}", i)],
            );
            provider.add_key(key, info).await.unwrap();
        }

        let stats = provider.get_stats().await;
        assert_eq!(stats.total_keys, 3);
        assert_eq!(stats.active_keys, 3);
    }

    #[tokio::test]
    async fn test_remove_api_key() {
        let provider = ApiKeyAuthProvider::new();
        let key = "sk_test_remove";
        let info = ApiKeyInfo::new("test_user".to_string(), vec!["read:users".to_string()]);

        provider.add_key(key.to_string(), info).await.unwrap();
        assert!(provider.get_key_info(key).await.is_some());

        let removed = provider.remove_key(key).await.unwrap();
        assert!(removed);
        assert!(provider.get_key_info(key).await.is_none());
    }
}